{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-02-26T11:03:31.881681Z",
     "start_time": "2025-02-26T11:03:31.753525Z"
    }
   },
   "outputs": [],
   "source": [
    "import hashlib\n",
    "import os\n",
    "import tarfile\n",
    "import zipfile\n",
    "import requests\n",
    "\n",
    "#@save\n",
    "DATA_HUB = dict()\n",
    "DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'"
   ]
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import platform\n",
    "proxy = \"http://127.0.0.1:7897\" if platform.system() == 'Darwin' else \"http://127.0.0.1:10808\"\n",
    "os.environ[\"HTTP_PROXY\"] = proxy\n",
    "os.environ[\"HTTPS_PROXY\"] = proxy"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-26T11:03:35.689721Z",
     "start_time": "2025-02-26T11:03:35.678721Z"
    }
   },
   "id": "a64e2152b6a8e87f",
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "('win32', 'Windows')"
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import sys\n",
    "sys.platform, platform.system()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-26T11:04:16.441041Z",
     "start_time": "2025-02-26T11:04:16.424042Z"
    }
   },
   "id": "82d0122721b7cbb7",
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "def download(name, cache_dir=os.path.join('..', 'data')):  #@save\n",
    "    \"\"\"下载一个DATA_HUB中的文件，返回本地文件名\"\"\"\n",
    "    assert name in DATA_HUB, f\"{name} 不存在于 {DATA_HUB}\"\n",
    "    url, sha1_hash = DATA_HUB[name]\n",
    "    os.makedirs(cache_dir, exist_ok=True)\n",
    "    fname = os.path.join(cache_dir, url.split('/')[-1])\n",
    "    if os.path.exists(fname):\n",
    "        sha1 = hashlib.sha1()\n",
    "        with open(fname, 'rb') as f:\n",
    "            while True:\n",
    "                data = f.read(1048576)\n",
    "                if not data:\n",
    "                    break\n",
    "                sha1.update(data)\n",
    "        if sha1.hexdigest() == sha1_hash:\n",
    "            return fname  # 命中缓存\n",
    "    print(f'正在从{url}下载{fname}...')\n",
    "    r = requests.get(url, stream=True, verify=True)\n",
    "    with open(fname, 'wb') as f:\n",
    "        f.write(r.content)\n",
    "    return fname"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-26T11:04:31.546960Z",
     "start_time": "2025-02-26T11:04:31.533961Z"
    }
   },
   "id": "5a076c1b47062851",
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "def download_extract(name, folder=None):  #@save\n",
    "    \"\"\"下载并解压zip/tar文件\"\"\"\n",
    "    fname = download(name)  # 假设download函数已经定义\n",
    "    base_dir = os.path.dirname(fname)\n",
    "    data_dir, ext = os.path.splitext(fname)\n",
    "    if ext == '.zip':\n",
    "        with zipfile.ZipFile(fname, 'r') as fp:\n",
    "            fp.extractall(base_dir)\n",
    "    elif ext in ('.tar', '.gz'):\n",
    "        with tarfile.open(fname, 'r') as fp:\n",
    "            fp.extractall(base_dir)\n",
    "    else:\n",
    "        assert False, '只有zip/tar文件可以被解压缩'\n",
    "    return os.path.join(base_dir, folder) if folder else data_dir\n",
    "\n",
    "def download_all():  #@save\n",
    "    \"\"\"下载DATA_HUB中的所有文件\"\"\"\n",
    "    for name in DATA_HUB:\n",
    "        download(name)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:52.957787Z",
     "start_time": "2025-02-25T09:00:52.952625Z"
    }
   },
   "id": "54d30b5c4108bffe",
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import torch\n",
    "from torch import nn\n",
    "import d2l\n",
    "\n",
    "DATA_HUB['kaggle_house_train'] = (  #@save\n",
    "    DATA_URL + 'kaggle_house_pred_train.csv',\n",
    "    '585e9cc93e70b39160e7921475f9bcd7d31219ce')\n",
    "\n",
    "DATA_HUB['kaggle_house_test'] = (  #@save\n",
    "    DATA_URL + 'kaggle_house_pred_test.csv',\n",
    "    'fa19780a7b011d9b009e8bff8e99922a8ee2eb90')"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-26T11:05:40.517763Z",
     "start_time": "2025-02-26T11:05:28.741760Z"
    }
   },
   "id": "28250506dfe9226e",
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "正在从http://d2l-data.s3-accelerate.amazonaws.com/kaggle_house_pred_train.csv下载..\\data\\kaggle_house_pred_train.csv...\n",
      "正在从http://d2l-data.s3-accelerate.amazonaws.com/kaggle_house_pred_test.csv下载..\\data\\kaggle_house_pred_test.csv...\n"
     ]
    }
   ],
   "source": [
    "train_data = pd.read_csv(download('kaggle_house_train'))\n",
    "test_data = pd.read_csv(download('kaggle_house_test'))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-26T11:05:48.316098Z",
     "start_time": "2025-02-26T11:05:44.745344Z"
    }
   },
   "id": "1c367bf815a54629",
   "execution_count": 7
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1460 entries, 0 to 1459\n",
      "Data columns (total 81 columns):\n",
      " #   Column         Non-Null Count  Dtype  \n",
      "---  ------         --------------  -----  \n",
      " 0   Id             1460 non-null   int64  \n",
      " 1   MSSubClass     1460 non-null   int64  \n",
      " 2   MSZoning       1460 non-null   object \n",
      " 3   LotFrontage    1201 non-null   float64\n",
      " 4   LotArea        1460 non-null   int64  \n",
      " 5   Street         1460 non-null   object \n",
      " 6   Alley          91 non-null     object \n",
      " 7   LotShape       1460 non-null   object \n",
      " 8   LandContour    1460 non-null   object \n",
      " 9   Utilities      1460 non-null   object \n",
      " 10  LotConfig      1460 non-null   object \n",
      " 11  LandSlope      1460 non-null   object \n",
      " 12  Neighborhood   1460 non-null   object \n",
      " 13  Condition1     1460 non-null   object \n",
      " 14  Condition2     1460 non-null   object \n",
      " 15  BldgType       1460 non-null   object \n",
      " 16  HouseStyle     1460 non-null   object \n",
      " 17  OverallQual    1460 non-null   int64  \n",
      " 18  OverallCond    1460 non-null   int64  \n",
      " 19  YearBuilt      1460 non-null   int64  \n",
      " 20  YearRemodAdd   1460 non-null   int64  \n",
      " 21  RoofStyle      1460 non-null   object \n",
      " 22  RoofMatl       1460 non-null   object \n",
      " 23  Exterior1st    1460 non-null   object \n",
      " 24  Exterior2nd    1460 non-null   object \n",
      " 25  MasVnrType     588 non-null    object \n",
      " 26  MasVnrArea     1452 non-null   float64\n",
      " 27  ExterQual      1460 non-null   object \n",
      " 28  ExterCond      1460 non-null   object \n",
      " 29  Foundation     1460 non-null   object \n",
      " 30  BsmtQual       1423 non-null   object \n",
      " 31  BsmtCond       1423 non-null   object \n",
      " 32  BsmtExposure   1422 non-null   object \n",
      " 33  BsmtFinType1   1423 non-null   object \n",
      " 34  BsmtFinSF1     1460 non-null   int64  \n",
      " 35  BsmtFinType2   1422 non-null   object \n",
      " 36  BsmtFinSF2     1460 non-null   int64  \n",
      " 37  BsmtUnfSF      1460 non-null   int64  \n",
      " 38  TotalBsmtSF    1460 non-null   int64  \n",
      " 39  Heating        1460 non-null   object \n",
      " 40  HeatingQC      1460 non-null   object \n",
      " 41  CentralAir     1460 non-null   object \n",
      " 42  Electrical     1459 non-null   object \n",
      " 43  1stFlrSF       1460 non-null   int64  \n",
      " 44  2ndFlrSF       1460 non-null   int64  \n",
      " 45  LowQualFinSF   1460 non-null   int64  \n",
      " 46  GrLivArea      1460 non-null   int64  \n",
      " 47  BsmtFullBath   1460 non-null   int64  \n",
      " 48  BsmtHalfBath   1460 non-null   int64  \n",
      " 49  FullBath       1460 non-null   int64  \n",
      " 50  HalfBath       1460 non-null   int64  \n",
      " 51  BedroomAbvGr   1460 non-null   int64  \n",
      " 52  KitchenAbvGr   1460 non-null   int64  \n",
      " 53  KitchenQual    1460 non-null   object \n",
      " 54  TotRmsAbvGrd   1460 non-null   int64  \n",
      " 55  Functional     1460 non-null   object \n",
      " 56  Fireplaces     1460 non-null   int64  \n",
      " 57  FireplaceQu    770 non-null    object \n",
      " 58  GarageType     1379 non-null   object \n",
      " 59  GarageYrBlt    1379 non-null   float64\n",
      " 60  GarageFinish   1379 non-null   object \n",
      " 61  GarageCars     1460 non-null   int64  \n",
      " 62  GarageArea     1460 non-null   int64  \n",
      " 63  GarageQual     1379 non-null   object \n",
      " 64  GarageCond     1379 non-null   object \n",
      " 65  PavedDrive     1460 non-null   object \n",
      " 66  WoodDeckSF     1460 non-null   int64  \n",
      " 67  OpenPorchSF    1460 non-null   int64  \n",
      " 68  EnclosedPorch  1460 non-null   int64  \n",
      " 69  3SsnPorch      1460 non-null   int64  \n",
      " 70  ScreenPorch    1460 non-null   int64  \n",
      " 71  PoolArea       1460 non-null   int64  \n",
      " 72  PoolQC         7 non-null      object \n",
      " 73  Fence          281 non-null    object \n",
      " 74  MiscFeature    54 non-null     object \n",
      " 75  MiscVal        1460 non-null   int64  \n",
      " 76  MoSold         1460 non-null   int64  \n",
      " 77  YrSold         1460 non-null   int64  \n",
      " 78  SaleType       1460 non-null   object \n",
      " 79  SaleCondition  1460 non-null   object \n",
      " 80  SalePrice      1460 non-null   int64  \n",
      "dtypes: float64(3), int64(35), object(43)\n",
      "memory usage: 924.0+ KB\n"
     ]
    }
   ],
   "source": [
    "train_data.info()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-26T11:05:59.166162Z",
     "start_time": "2025-02-26T11:05:59.110224Z"
    }
   },
   "id": "c6f909ff91894b02",
   "execution_count": 8
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1460, 81)\n",
      "(1459, 80)\n"
     ]
    }
   ],
   "source": [
    "print(train_data.shape)\n",
    "print(test_data.shape)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.571183Z",
     "start_time": "2025-02-25T09:00:56.568148Z"
    }
   },
   "id": "8d21fcb973a14585",
   "execution_count": 8
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   Id  MSSubClass MSZoning  LotFrontage SaleType SaleCondition  SalePrice\n",
      "0   1          60       RL         65.0       WD        Normal     208500\n",
      "1   2          20       RL         80.0       WD        Normal     181500\n",
      "2   3          60       RL         68.0       WD        Normal     223500\n",
      "3   4          70       RL         60.0       WD       Abnorml     140000\n"
     ]
    }
   ],
   "source": [
    "print(train_data.iloc[0:4, [0, 1, 2, 3, -3, -2, -1]])"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.579450Z",
     "start_time": "2025-02-25T09:00:56.572649Z"
    }
   },
   "id": "7c2e3f1c389d8060",
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.588605Z",
     "start_time": "2025-02-25T09:00:56.580885Z"
    }
   },
   "id": "d129e02c2f22045c",
   "execution_count": 10
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 2919 entries, 0 to 1458\n",
      "Data columns (total 79 columns):\n",
      " #   Column         Non-Null Count  Dtype  \n",
      "---  ------         --------------  -----  \n",
      " 0   MSSubClass     2919 non-null   int64  \n",
      " 1   MSZoning       2915 non-null   object \n",
      " 2   LotFrontage    2433 non-null   float64\n",
      " 3   LotArea        2919 non-null   int64  \n",
      " 4   Street         2919 non-null   object \n",
      " 5   Alley          198 non-null    object \n",
      " 6   LotShape       2919 non-null   object \n",
      " 7   LandContour    2919 non-null   object \n",
      " 8   Utilities      2917 non-null   object \n",
      " 9   LotConfig      2919 non-null   object \n",
      " 10  LandSlope      2919 non-null   object \n",
      " 11  Neighborhood   2919 non-null   object \n",
      " 12  Condition1     2919 non-null   object \n",
      " 13  Condition2     2919 non-null   object \n",
      " 14  BldgType       2919 non-null   object \n",
      " 15  HouseStyle     2919 non-null   object \n",
      " 16  OverallQual    2919 non-null   int64  \n",
      " 17  OverallCond    2919 non-null   int64  \n",
      " 18  YearBuilt      2919 non-null   int64  \n",
      " 19  YearRemodAdd   2919 non-null   int64  \n",
      " 20  RoofStyle      2919 non-null   object \n",
      " 21  RoofMatl       2919 non-null   object \n",
      " 22  Exterior1st    2918 non-null   object \n",
      " 23  Exterior2nd    2918 non-null   object \n",
      " 24  MasVnrType     1153 non-null   object \n",
      " 25  MasVnrArea     2896 non-null   float64\n",
      " 26  ExterQual      2919 non-null   object \n",
      " 27  ExterCond      2919 non-null   object \n",
      " 28  Foundation     2919 non-null   object \n",
      " 29  BsmtQual       2838 non-null   object \n",
      " 30  BsmtCond       2837 non-null   object \n",
      " 31  BsmtExposure   2837 non-null   object \n",
      " 32  BsmtFinType1   2840 non-null   object \n",
      " 33  BsmtFinSF1     2918 non-null   float64\n",
      " 34  BsmtFinType2   2839 non-null   object \n",
      " 35  BsmtFinSF2     2918 non-null   float64\n",
      " 36  BsmtUnfSF      2918 non-null   float64\n",
      " 37  TotalBsmtSF    2918 non-null   float64\n",
      " 38  Heating        2919 non-null   object \n",
      " 39  HeatingQC      2919 non-null   object \n",
      " 40  CentralAir     2919 non-null   object \n",
      " 41  Electrical     2918 non-null   object \n",
      " 42  1stFlrSF       2919 non-null   int64  \n",
      " 43  2ndFlrSF       2919 non-null   int64  \n",
      " 44  LowQualFinSF   2919 non-null   int64  \n",
      " 45  GrLivArea      2919 non-null   int64  \n",
      " 46  BsmtFullBath   2917 non-null   float64\n",
      " 47  BsmtHalfBath   2917 non-null   float64\n",
      " 48  FullBath       2919 non-null   int64  \n",
      " 49  HalfBath       2919 non-null   int64  \n",
      " 50  BedroomAbvGr   2919 non-null   int64  \n",
      " 51  KitchenAbvGr   2919 non-null   int64  \n",
      " 52  KitchenQual    2918 non-null   object \n",
      " 53  TotRmsAbvGrd   2919 non-null   int64  \n",
      " 54  Functional     2917 non-null   object \n",
      " 55  Fireplaces     2919 non-null   int64  \n",
      " 56  FireplaceQu    1499 non-null   object \n",
      " 57  GarageType     2762 non-null   object \n",
      " 58  GarageYrBlt    2760 non-null   float64\n",
      " 59  GarageFinish   2760 non-null   object \n",
      " 60  GarageCars     2918 non-null   float64\n",
      " 61  GarageArea     2918 non-null   float64\n",
      " 62  GarageQual     2760 non-null   object \n",
      " 63  GarageCond     2760 non-null   object \n",
      " 64  PavedDrive     2919 non-null   object \n",
      " 65  WoodDeckSF     2919 non-null   int64  \n",
      " 66  OpenPorchSF    2919 non-null   int64  \n",
      " 67  EnclosedPorch  2919 non-null   int64  \n",
      " 68  3SsnPorch      2919 non-null   int64  \n",
      " 69  ScreenPorch    2919 non-null   int64  \n",
      " 70  PoolArea       2919 non-null   int64  \n",
      " 71  PoolQC         10 non-null     object \n",
      " 72  Fence          571 non-null    object \n",
      " 73  MiscFeature    105 non-null    object \n",
      " 74  MiscVal        2919 non-null   int64  \n",
      " 75  MoSold         2919 non-null   int64  \n",
      " 76  YrSold         2919 non-null   int64  \n",
      " 77  SaleType       2918 non-null   object \n",
      " 78  SaleCondition  2919 non-null   object \n",
      "dtypes: float64(11), int64(25), object(43)\n",
      "memory usage: 1.8+ MB\n"
     ]
    }
   ],
   "source": [
    "all_features.info()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.605141Z",
     "start_time": "2025-02-25T09:00:56.589803Z"
    }
   },
   "id": "4faa2abf3fed8708",
   "execution_count": 11
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "dtypes = all_features.dtypes"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.609270Z",
     "start_time": "2025-02-25T09:00:56.606595Z"
    }
   },
   "id": "2dd210e2a3256e83",
   "execution_count": 12
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "MSSubClass         int64\nMSZoning          object\nLotFrontage      float64\nLotArea            int64\nStreet            object\n                  ...   \nMiscVal            int64\nMoSold             int64\nYrSold             int64\nSaleType          object\nSaleCondition     object\nLength: 79, dtype: object"
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dtypes"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.617103Z",
     "start_time": "2025-02-25T09:00:56.610673Z"
    }
   },
   "id": "f0bb7714a6f49e9b",
   "execution_count": 13
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "3"
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dtypes.nunique()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.625570Z",
     "start_time": "2025-02-25T09:00:56.621589Z"
    }
   },
   "id": "909a987b151dc72d",
   "execution_count": 14
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "object     43\nint64      25\nfloat64    11\nName: count, dtype: int64"
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dtypes.value_counts()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.632264Z",
     "start_time": "2025-02-25T09:00:56.627105Z"
    }
   },
   "id": "9f8158c8b8b804a5",
   "execution_count": 15
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# 若无法获得测试数据，则可根据训练数据计算均值和标准差\n",
    "numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index\n",
    "all_features[numeric_features] = all_features[numeric_features].apply(\n",
    "    lambda x: (x - x.mean()) / (x.std()))\n",
    "# 在标准化数据之后，所有均值消失，因此我们可以将缺失值设置为0\n",
    "all_features[numeric_features] = all_features[numeric_features].fillna(0)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.661236Z",
     "start_time": "2025-02-25T09:00:56.633827Z"
    }
   },
   "id": "210190f9203f7440",
   "execution_count": 16
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 2919 entries, 0 to 1458\n",
      "Data columns (total 79 columns):\n",
      " #   Column         Non-Null Count  Dtype  \n",
      "---  ------         --------------  -----  \n",
      " 0   MSSubClass     2919 non-null   float64\n",
      " 1   MSZoning       2915 non-null   object \n",
      " 2   LotFrontage    2919 non-null   float64\n",
      " 3   LotArea        2919 non-null   float64\n",
      " 4   Street         2919 non-null   object \n",
      " 5   Alley          198 non-null    object \n",
      " 6   LotShape       2919 non-null   object \n",
      " 7   LandContour    2919 non-null   object \n",
      " 8   Utilities      2917 non-null   object \n",
      " 9   LotConfig      2919 non-null   object \n",
      " 10  LandSlope      2919 non-null   object \n",
      " 11  Neighborhood   2919 non-null   object \n",
      " 12  Condition1     2919 non-null   object \n",
      " 13  Condition2     2919 non-null   object \n",
      " 14  BldgType       2919 non-null   object \n",
      " 15  HouseStyle     2919 non-null   object \n",
      " 16  OverallQual    2919 non-null   float64\n",
      " 17  OverallCond    2919 non-null   float64\n",
      " 18  YearBuilt      2919 non-null   float64\n",
      " 19  YearRemodAdd   2919 non-null   float64\n",
      " 20  RoofStyle      2919 non-null   object \n",
      " 21  RoofMatl       2919 non-null   object \n",
      " 22  Exterior1st    2918 non-null   object \n",
      " 23  Exterior2nd    2918 non-null   object \n",
      " 24  MasVnrType     1153 non-null   object \n",
      " 25  MasVnrArea     2919 non-null   float64\n",
      " 26  ExterQual      2919 non-null   object \n",
      " 27  ExterCond      2919 non-null   object \n",
      " 28  Foundation     2919 non-null   object \n",
      " 29  BsmtQual       2838 non-null   object \n",
      " 30  BsmtCond       2837 non-null   object \n",
      " 31  BsmtExposure   2837 non-null   object \n",
      " 32  BsmtFinType1   2840 non-null   object \n",
      " 33  BsmtFinSF1     2919 non-null   float64\n",
      " 34  BsmtFinType2   2839 non-null   object \n",
      " 35  BsmtFinSF2     2919 non-null   float64\n",
      " 36  BsmtUnfSF      2919 non-null   float64\n",
      " 37  TotalBsmtSF    2919 non-null   float64\n",
      " 38  Heating        2919 non-null   object \n",
      " 39  HeatingQC      2919 non-null   object \n",
      " 40  CentralAir     2919 non-null   object \n",
      " 41  Electrical     2918 non-null   object \n",
      " 42  1stFlrSF       2919 non-null   float64\n",
      " 43  2ndFlrSF       2919 non-null   float64\n",
      " 44  LowQualFinSF   2919 non-null   float64\n",
      " 45  GrLivArea      2919 non-null   float64\n",
      " 46  BsmtFullBath   2919 non-null   float64\n",
      " 47  BsmtHalfBath   2919 non-null   float64\n",
      " 48  FullBath       2919 non-null   float64\n",
      " 49  HalfBath       2919 non-null   float64\n",
      " 50  BedroomAbvGr   2919 non-null   float64\n",
      " 51  KitchenAbvGr   2919 non-null   float64\n",
      " 52  KitchenQual    2918 non-null   object \n",
      " 53  TotRmsAbvGrd   2919 non-null   float64\n",
      " 54  Functional     2917 non-null   object \n",
      " 55  Fireplaces     2919 non-null   float64\n",
      " 56  FireplaceQu    1499 non-null   object \n",
      " 57  GarageType     2762 non-null   object \n",
      " 58  GarageYrBlt    2919 non-null   float64\n",
      " 59  GarageFinish   2760 non-null   object \n",
      " 60  GarageCars     2919 non-null   float64\n",
      " 61  GarageArea     2919 non-null   float64\n",
      " 62  GarageQual     2760 non-null   object \n",
      " 63  GarageCond     2760 non-null   object \n",
      " 64  PavedDrive     2919 non-null   object \n",
      " 65  WoodDeckSF     2919 non-null   float64\n",
      " 66  OpenPorchSF    2919 non-null   float64\n",
      " 67  EnclosedPorch  2919 non-null   float64\n",
      " 68  3SsnPorch      2919 non-null   float64\n",
      " 69  ScreenPorch    2919 non-null   float64\n",
      " 70  PoolArea       2919 non-null   float64\n",
      " 71  PoolQC         10 non-null     object \n",
      " 72  Fence          571 non-null    object \n",
      " 73  MiscFeature    105 non-null    object \n",
      " 74  MiscVal        2919 non-null   float64\n",
      " 75  MoSold         2919 non-null   float64\n",
      " 76  YrSold         2919 non-null   float64\n",
      " 77  SaleType       2918 non-null   object \n",
      " 78  SaleCondition  2919 non-null   object \n",
      "dtypes: float64(36), object(43)\n",
      "memory usage: 1.8+ MB\n"
     ]
    }
   ],
   "source": [
    "all_features.info()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.679416Z",
     "start_time": "2025-02-25T09:00:56.662333Z"
    }
   },
   "id": "776275d3350a621b",
   "execution_count": 17
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "(2919, 330)"
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# “Dummy_na=True”将“na”（缺失值）视为有效的特征值，并为其创建指示符特征\n",
    "all_features = pd.get_dummies(all_features, dummy_na=True)\n",
    "all_features.shape"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.722987Z",
     "start_time": "2025-02-25T09:00:56.680790Z"
    }
   },
   "id": "b62bf6e9a24c9975",
   "execution_count": 18
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 2919 entries, 0 to 1458\n",
      "Columns: 330 entries, MSSubClass to SaleCondition_nan\n",
      "dtypes: bool(294), float64(36)\n",
      "memory usage: 1.6 MB\n"
     ]
    }
   ],
   "source": [
    "all_features.info()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.739319Z",
     "start_time": "2025-02-25T09:00:56.724186Z"
    }
   },
   "id": "5f7cf83335fcef16",
   "execution_count": 19
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "(1460, 81)"
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data.shape"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T09:00:56.745908Z",
     "start_time": "2025-02-25T09:00:56.740961Z"
    }
   },
   "id": "65ca3ee5cca850dd",
   "execution_count": 20
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "n_train = train_data.shape[0]\n",
    "train_features = torch.tensor(all_features[:n_train].to_numpy('float32'), dtype=torch.float32)\n",
    "test_features = torch.tensor(all_features[n_train:].to_numpy('float32'), dtype=torch.float32)\n",
    "train_labels = torch.tensor(\n",
    "    train_data.SalePrice.values.reshape(-1, 1), dtype=torch.float32)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T11:02:29.400254Z",
     "start_time": "2025-02-25T11:02:29.381753Z"
    }
   },
   "id": "3dc03be0b882d7d1",
   "execution_count": 31
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "loss = nn.MSELoss()\n",
    "in_features = train_features.shape[1]\n",
    "\n",
    "def get_net():\n",
    "    net = nn.Sequential(nn.Linear(in_features,1))\n",
    "    return net"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T12:33:03.840107Z",
     "start_time": "2025-02-25T12:33:03.835922Z"
    }
   },
   "id": "f90d45fb38ee581c",
   "execution_count": 32
  },
  {
   "cell_type": "markdown",
   "source": [
    "房价就像股票价格一样，我们关心的是相对数量，而不是绝对数量。 因此，我们更关心相对误差， 而不是绝对误差\n",
    "。 例如，如果我们在俄亥俄州农村地区估计一栋房子的价格时， 假设我们的预测偏差了10万美元， 然而那里一栋典型的房子的价值是12.5万美元， 那么模型可能做得很糟糕。 另一方面，如果我们在加州豪宅区的预测出现同样的10万美元的偏差， （在那里，房价中位数超过400万美元） 这可能是一个不错的预测。\n",
    "解决这个问题的一种方法是用价格预测的对数来衡量差异：\n",
    "$\\sqrt{\\frac{1}{n}\\sum_{i=1}^n\\left(\\log y_i -\\log \\hat{y}_i\\right)^2}.$"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "8803e68a9b891b"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "def log_rmse(net, features, labels):\n",
    "    # 为了在取对数时进一步稳定该值，将小于1的值设置为1\n",
    "    clipped_preds = torch.clamp(net(features), 1, float('inf')) # float('inf')可省略\n",
    "    rmse = torch.sqrt(loss(torch.log(clipped_preds),\n",
    "                           torch.log(labels)))\n",
    "    return rmse.item()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T12:58:27.413519Z",
     "start_time": "2025-02-25T12:58:27.409485Z"
    }
   },
   "id": "d153e896bd06765d",
   "execution_count": 33
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "def train(net, train_features, train_labels, test_features, test_labels,\n",
    "          num_epochs, learning_rate, weight_decay, batch_size):\n",
    "    train_ls, test_ls = [], []\n",
    "    train_iter = d2l.load_array((train_features, train_labels), batch_size)\n",
    "    # 这里使用的是Adam优化算法\n",
    "    optimizer = torch.optim.Adam(net.parameters(),\n",
    "                                 lr = learning_rate,\n",
    "                                 weight_decay = weight_decay)\n",
    "    for epoch in range(num_epochs):\n",
    "        for X, y in train_iter:\n",
    "            optimizer.zero_grad()\n",
    "            l = loss(net(X), y)\n",
    "            l.backward()\n",
    "            optimizer.step()\n",
    "        train_ls.append(log_rmse(net, train_features, train_labels))\n",
    "        if test_labels is not None:\n",
    "            test_ls.append(log_rmse(net, test_features, test_labels))\n",
    "    return train_ls, test_ls"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "e9da314e842d9dc5"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# TODO 手写交叉验证太复杂了，暂时没有心情"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "cd0f38b4d70748f9"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
